package com.rybbaby.tss.platform.initializer;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.rybbaby.tss.core.initializer.AbstractAutomaticInit;
import com.rybbaby.tss.core.redis.RedisClient;
import com.rybbaby.tss.core.utils.DateUtil;
import com.rybbaby.tss.core.utils.JSONUtil;
import com.rybbaby.tss.core.utils.SpringApplicationContextUtil;
import com.rybbaby.tss.platform.sysAdminUserJoinSysMenuPermissions.entity.SysAdminUserJoinSysMenuPermissions;
import com.rybbaby.tss.platform.sysHandlePermissions.entity.SysHandlePermissions;
import com.rybbaby.tss.platform.sysHandlePermissions.service.ISysHandlePermissionsService;
import com.rybbaby.tss.platform.sysHandlePermissionsAttrs.entity.SysHandlePermissionsAttrs;
import com.rybbaby.tss.platform.sysHandlePermissionsAttrs.service.ISysHandlePermissionsAttrsService;
import com.rybbaby.tss.platform.sysHandlePermissionsClasses.entity.SysHandlePermissionsClasses;
import com.rybbaby.tss.platform.sysHandlePermissionsClasses.service.ISysHandlePermissionsClassesService;
import com.rybbaby.tss.platform.sysHandlePermissionsEvents.entity.SysHandlePermissionsEvents;
import com.rybbaby.tss.platform.sysHandlePermissionsEvents.service.ISysHandlePermissionsEventsService;
import com.rybbaby.tss.platform.sysHandlePermissionsStyles.entity.SysHandlePermissionsStyles;
import com.rybbaby.tss.platform.sysHandlePermissionsStyles.service.ISysHandlePermissionsStylesService;
import com.rybbaby.tss.platform.sysMenuPermissions.entity.SysMenuPermissions;
import com.rybbaby.tss.platform.sysRoleJoinSysMenuPermissions.entity.SysRoleJoinSysMenuPermissions;
import com.rybbaby.tss.platform.websocket.service.PlatformWebsocketMsgService;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.json.JSONArray;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;

import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author 谢进伟
 * @description 操作权限初始化器 , 该初始化器将缓存所有的操作权限
 * @createDate 2016年12月8日 上午11:03:04
 */
public class HandlePermissionsInitializer extends AbstractAutomaticInit {

    private static Logger log = Logger.getLogger(HandlePermissionsInitializer.class);

    /**
     * 登录用户私有菜单权限分配缓存后缀
     **/
    private static String cacheUserPermissionAllotSuffix = "UserPermissionAllot";
    /**
     * 登录用户拥有的角色所对应的菜单权限后缀
     **/
    private static String cacheRolePermissionAllotSuffix = "RolePermissionAllot";
    /**
     * 缓存操作权限key标识值
     */
    public static final String HANDLEPERMISSIONCACHEKEYIDENTIFYING = "handlePermissionCacheC4A2F906C9F87588C56AFE48C6C965893C36374F18611C8B2F17F4D671D8FEE1";
    /**
     * 权限缓存分隔符
     **/
    private static String separator = "-";
    /**
     * ehcache缓存管理
     **/
    private static CacheManager ehcacheManager;
    /**
     * 操作权限缓存容器
     **/
    private static Cache handlePermissionEhcache;

    /**
     * 在线用户操作权限分配缓存1
     **/
    private static Cache onlineUserPermissionAllotEhcache;
    /**
     * 重新加载操作权限的队列
     */
    private static ConcurrentLinkedQueue<List<SysHandlePermissions>> reloadQueue = new ConcurrentLinkedQueue();

    /**
     * webSocket消息服务
     */
    private static PlatformWebsocketMsgService platformWebsocketMsgService;

    /**
     * 定时器，用来更新缓存
     */
    private static Timer timer = null;

    static {
        ehcacheManager = SpringApplicationContextUtil.getContext().getBean(CacheManager.class);
        platformWebsocketMsgService = SpringApplicationContextUtil.getContext().getBean(PlatformWebsocketMsgService.class);
        handlePermissionEhcache = ehcacheManager.getCache("hanldePermissionEhcache");
        onlineUserPermissionAllotEhcache = ehcacheManager.getCache("onlineUserPermissionAllotEhcache");
    }

    @Override
    public void autoInit() {
        loadAllHandlePermission();
        startTimer(true);

    }

    /**
     * 获取当前的正在等待刷新权限的队列数
     *
     * @return
     */
    public static int getQueueCount() {
        return reloadQueue.size();
    }

    /**
     * 启动定时器
     *
     * @param isFirstStart 是否为第一次启动
     */
    private static void startTimer(boolean isFirstStart) {
        if (timer != null) {
            try {
                if (!isFirstStart) {
                    timer.cancel();//关闭定时器
                }
            } catch (Exception e) {
                log.info("关闭定时器出现异常");
                e.printStackTrace();
            }
        }
        timer = new Timer();
        // 启动给一个定时任务，每个1秒检查一下重新加载操作权限的队列中是否有值，如果有则重新加载队列
        timer.scheduleAtFixedRate(getTask(), 1000, 1000);
    }

    /**
     * 重启定时器
     */
    private static void restartTimer() {
        startTimer(false);
    }

    /**
     * 强制重新加载操作权限
     */
    public static void enforcementReloadAlLHandlePermissoin() {
        if (RedisClient.isCanUse()) {
            Set<String> keys = RedisClient.keys(HANDLEPERMISSIONCACHEKEYIDENTIFYING + "*");
            String[] delKeys = new String[keys.size()];
            RedisClient.del(keys.toArray(delKeys));
        } else {
            handlePermissionEhcache.removeAll();
        }
        // 清空队列
        reloadQueue.clear();
        // 注册新任务
        registerReloadTask(null);
        // 重启定时器
        restartTimer();
    }

    /**
     * 获取定时任务
     *
     * @return
     */
    private static TimerTask getTask() {
        return new TimerTask() {
            @Override
            public void run() {
                if (!reloadQueue.isEmpty()) {
                    try {
                        if (platformWebsocketMsgService != null) {
                            platformWebsocketMsgService.broadcast("系统广播", "<br>管理员已将操作权限更新<br>若有给您分配新的权限<br>重新登录将可使用新的操作权限！");
                        }
                        log.info("reloading handle permissions ....");
                        List<SysHandlePermissions> removeHandlePermissionsList = reloadQueue.poll();
                        // 移除需要清理的操作权限缓存
                        if (removeHandlePermissionsList != null && !removeHandlePermissionsList.isEmpty()) {
                            List<String> delKeys = new ArrayList<>();
                            for (SysHandlePermissions rhp : removeHandlePermissionsList) {
                                if (StringUtils.isBlank(rhp.getHandlePermissionIdentifier())) {
                                    String menuId = rhp.getMenuId();
                                    SysMenuPermissions menuPermission = MenuPermissionsInitializer.getMenuPermission(menuId);
                                    rhp.setHandlePermissionIdentifier(menuPermission.getHandlePermissionIdentifier());
                                }
                                String key = getHandlePermissionCacheKey(rhp);
                                delKeys.add(key);
                            }
                            boolean redisCanUse = RedisClient.isCanUse();//redis 是否可用
                            log.info("正在移除操作权限：" + StringUtils.join(delKeys.toArray(), ","));
                            if (redisCanUse) {
                                //*********Redis 缓存*********
                                RedisClient.del(delKeys.toArray(new String[delKeys.size()]));
                            } else {
                                //*********本地缓存***********
                                // 移除缓存
                                handlePermissionEhcache.removeAll(delKeys);
                            }
                        }
                        // 重新加载权限
                        loadAllHandlePermission();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    }

    /**
     * 注册重新加载的任务
     *
     * @param removeHandlePermissionsList 需要移除的操作权限
     */
    private static void registerReloadTask(List<SysHandlePermissions> removeHandlePermissionsList) {
        if (removeHandlePermissionsList == null) {
            removeHandlePermissionsList = new ArrayList<>();
        }
        reloadQueue.offer(removeHandlePermissionsList);
    }

    /**
     * 重新加载操作权限，当操作权限的 Class 、 Attr 、Style 、 Event 更新时，调用此方法来更新缓存
     */
    public static void reloadHandlePermission() {
        registerReloadTask(null);
    }

    /**
     * 重新加载操作权限
     *
     * @param removeHandlePermissions 需要移除的操作权限，如果重新分配了操作权限，此参数一定要传入，避免缓存造成权限错误
     */
    public static void reloadHandlePermission(SysHandlePermissions removeHandlePermissions) {
        List<SysHandlePermissions> removeHandlePermissionsList = new ArrayList<>();
        removeHandlePermissionsList.add(removeHandlePermissions);
        registerReloadTask(removeHandlePermissionsList);
    }

    /**
     * 重新加载操作权限
     *
     * @param removeHandlePermissionsList 需要移除的操作权限列表，如果重新分配了操作权限，此参数一定要传入，避免因为缓存未及时更新造成权限错误
     */
    public static void reloadHandlePermission(List<SysHandlePermissions> removeHandlePermissionsList) {
        registerReloadTask(removeHandlePermissionsList);
    }

    private static List<SysHandlePermissions> converToList(List<Map<String, Object>> maps) {
        List<SysHandlePermissions> list = new ArrayList<>();
        for (Map<String, Object> shpMap : maps) {
            if (shpMap != null && !shpMap.isEmpty()) {
                Object objCode = shpMap.get("code");
                Object handlePermissionIdentifier = shpMap.get("handlePermissionIdentifier");
                if (handlePermissionIdentifier == null || objCode == null) {
                    continue;
                }
                String objName = shpMap.get("name").toString();
                Object isForbidden = shpMap.get("isForbidden");
                Object objInnerHtml = shpMap.get("innerHtml");
                Object objIdAttr = shpMap.get("idAttr");
                Object objWeight = shpMap.get("weight");
                Object objAdminUserPermissionAllotId = shpMap.get("adminUserPermissionAllotId");
                Object objRolePermissionAllotId = shpMap.get("rolePermissionAllotId");
                Object defaultHandlePermissionId = shpMap.get("defaultHandlePermissionId");
                Object objMenuName = shpMap.get("menuName");
                SysHandlePermissions shp = new SysHandlePermissions();
                shp.setAdminUserPermissionAllotId(objAdminUserPermissionAllotId == null ? null : objAdminUserPermissionAllotId.toString());
                shp.setRolePermissionAllotId(objRolePermissionAllotId == null ? null : objRolePermissionAllotId.toString());
                shp.setHandlePermissionIdentifier(handlePermissionIdentifier.toString());
                shp.setCode(objCode.toString());
                shp.setId(shpMap.get("id").toString());
                shp.setName(shpMap.get("name") != null ? objName : "");
                shp.setTagName(shpMap.get("tagName").toString());
                shp.setInnerHtml(objInnerHtml != null ? objInnerHtml.toString() : "");
                shp.setIdAttr(objIdAttr != null ? objIdAttr.toString() : "");
                shp.setWeight(objWeight == null ? 0 : Integer.parseInt(objWeight.toString()));
                shp.setDefaultHandlePermissionId(defaultHandlePermissionId == null ? null : defaultHandlePermissionId.toString());
                shp.setMenuName(objMenuName == null ? null : objMenuName.toString());
                shp.setIsForbidden(isForbidden == null ? false : (isForbidden.toString().equals("1") ? true : false));
                list.add(shp);
            }
        }
        return list;
    }

    /**
     * 重新加载所有操作权限
     */
    private static synchronized void loadAllHandlePermission() {
        long startTime = System.currentTimeMillis();
        boolean redisCanUse = RedisClient.isCanUse();//redis 是否可用
        //获取service
        ISysHandlePermissionsService sysHandlePermissionsService = SpringApplicationContextUtil.getContext().getBean(ISysHandlePermissionsService.class);
        ISysHandlePermissionsClassesService sysHandlePermissionsClassesService = SpringApplicationContextUtil.getContext().getBean(ISysHandlePermissionsClassesService.class);
        ISysHandlePermissionsStylesService sysHandlePermissionsStylesService = SpringApplicationContextUtil.getContext().getBean(ISysHandlePermissionsStylesService.class);
        ISysHandlePermissionsAttrsService sysHandlePermissionsAttrsService = SpringApplicationContextUtil.getContext().getBean(ISysHandlePermissionsAttrsService.class);
        ISysHandlePermissionsEventsService sysHandlePermissionsEventsService = SpringApplicationContextUtil.getContext().getBean(ISysHandlePermissionsEventsService.class);

        // 所有非默认菜单权限sql
        StringBuffer baseSql = new StringBuffer();
        baseSql.append("SELECT shp.id,shp.isForbidden isForbidden,defaultHandlePermissionId, shp.name, shp.code, shp.tagName, shp.innerHtml, shp.idAttr, shp.weight,shp.adminUserPermissionAllotId,shp.rolePermissionAllotId, ");
        baseSql.append("(SELECT smp.name  FROM sys_menu_permissions smp WHERE id =shp.menuId) menuName, ");
        baseSql.append("(SELECT smp.handlePermissionIdentifier  FROM sys_menu_permissions smp WHERE id=shp.menuId) handlePermissionIdentifier ");
        baseSql.append(" FROM sys_handle_permissions shp WHERE ((shp.adminUserPermissionAllotId IS NOT NULL AND shp.rolePermissionAllotId IS NULL) OR (shp.adminUserPermissionAllotId IS NULL AND shp.rolePermissionAllotId IS NOT NULL)) ");
        baseSql.append(" AND shp.defaultHandlePermissionId IS NOT NULL AND shp.isForbidden IS NOT NULL");

        // 加载所有被禁用的操作权限
        StringBuffer sql_forForbidden = new StringBuffer(baseSql).append(" AND isForbidden=1");
        List<Map<String, Object>> forbiddenHandlePermission = sysHandlePermissionsService.findForJdbc(sql_forForbidden.toString(), new Object[]{});
        List<SysHandlePermissions> forbiddenHandlePermissionList = converToList(forbiddenHandlePermission);
        if (forbiddenHandlePermissionList != null && !forbiddenHandlePermissionList.isEmpty()) {
            // 从缓存中删除禁用的操作权限
            List<String> delKeys = new ArrayList<>();
            forbiddenHandlePermissionList.forEach((shp) -> {
                delKeys.add(getHandlePermissionCacheKey(shp));
            });
            if (redisCanUse) {
                RedisClient.del(StringUtils.join(delKeys, ",").split(","));
            } else {
                handlePermissionEhcache.removeAll(delKeys);
            }
        }

        // 加载所有未被禁用的操作权限
        StringBuffer sql_forNotForbidden = new StringBuffer(baseSql).append(" AND isForbidden=0");
        List<Map<String, Object>> shpList = sysHandlePermissionsService.findForJdbc(sql_forNotForbidden.toString(), new Object[]{});
        List<SysHandlePermissions> notForbiddenHandlePermissionList = converToList(shpList);
        List<String> ids = new ArrayList<>();
        notForbiddenHandlePermissionList.forEach((shp) -> {
            ids.add(shp.getDefaultHandlePermissionId());
        });
        // 加载所有未被禁用操作权限的Class属性
        DetachedCriteria dc_class = DetachedCriteria.forClass(SysHandlePermissionsClasses.class);
        dc_class.add(Restrictions.eq("isForbidden", false));
        if(ids!=null&&!ids.isEmpty()){
            dc_class.add(Restrictions.in("handlePermissionId", ids));
        }
        List<SysHandlePermissionsClasses> allClass = sysHandlePermissionsClassesService.findByDetached(dc_class);

        // 加载所有未被禁用操作权限的Style属性
        DetachedCriteria dc_style = DetachedCriteria.forClass(SysHandlePermissionsStyles.class);
        dc_class.add(Restrictions.eq("isForbidden", false));
        dc_class.add(Restrictions.in("handlePermissionId", ids));
        List<SysHandlePermissionsStyles> allStyle = sysHandlePermissionsStylesService.findByDetached(dc_style);

        // 加载所有未被禁用操作权限的自定义事件
        DetachedCriteria dc_event = DetachedCriteria.forClass(SysHandlePermissionsEvents.class);
        dc_class.add(Restrictions.eq("isForbidden", false));
        dc_class.add(Restrictions.in("handlePermissionId", ids));
        List<SysHandlePermissionsEvents> allEvent = sysHandlePermissionsEventsService.findByDetached(dc_event);

        // 加载所有未被禁用操作权限的自定义属性
        DetachedCriteria dc_attr = DetachedCriteria.forClass(SysHandlePermissionsAttrs.class);
        dc_class.add(Restrictions.eq("isForbidden", false));
        dc_class.add(Restrictions.in("handlePermissionId", ids));
        List<SysHandlePermissionsAttrs> allAttr = sysHandlePermissionsAttrsService.findByDetached(dc_attr);

        // 缓存操作权限
        for (SysHandlePermissions shp : notForbiddenHandlePermissionList) {
            String objCode = shp.getCode();
            String handlePermissionIdentifier = shp.getHandlePermissionIdentifier();
            if (handlePermissionIdentifier == null || objCode == null) {
                continue;
            }
            String handlePermissionId = shp.getDefaultHandlePermissionId();
            String key = getHandlePermissionCacheKey(shp);
            // 加载所有的操作权限Class属性
            List<SysHandlePermissionsClasses> delClasses = new ArrayList<>();
            List<SysHandlePermissionsClasses> classesClone = new ArrayList<>();
            for (SysHandlePermissionsClasses clas : allClass) {
                if (clas.getHandlePermissionId().equals(handlePermissionId)) {
                    SysHandlePermissionsClasses newClass = new SysHandlePermissionsClasses();
                    BeanUtils.copyProperties(clas, newClass, "handlePermission");
                    delClasses.add(clas);
                    classesClone.add(newClass);
                }
            }

            // 加载所有的操作权限style属性
            List<SysHandlePermissionsStyles> delStyle = new ArrayList<>();
            List<SysHandlePermissionsStyles> stylesClone = new ArrayList<>();
            for (SysHandlePermissionsStyles style : allStyle) {
                if (style.getHandlePermissionId().equals(handlePermissionId)) {
                    SysHandlePermissionsStyles newStyle = new SysHandlePermissionsStyles();
                    BeanUtils.copyProperties(style, newStyle, "handlePermission");
                    delStyle.add(style);
                    stylesClone.add(newStyle);
                }
            }

            // 加载所有的操作权限自定义事件
            List<SysHandlePermissionsEvents> delEvent = new ArrayList<>();
            List<SysHandlePermissionsEvents> eventsClone = new ArrayList<>();
            for (SysHandlePermissionsEvents event : allEvent) {
                if (event.getHandlePermissionId().equals(handlePermissionId)) {
                    SysHandlePermissionsEvents newEvent = new SysHandlePermissionsEvents();
                    BeanUtils.copyProperties(event, newEvent, "handlePermission");
                    delEvent.add(event);
                    eventsClone.add(newEvent);
                }
            }

            // 加载所有的操作权限自定义属性
            List<SysHandlePermissionsAttrs> delAttr = new ArrayList<>();
            List<SysHandlePermissionsAttrs> attrsClone = new ArrayList<>();
            for (SysHandlePermissionsAttrs attr : allAttr) {
                if (attr.getHandlePermissionId().equals(handlePermissionId)) {
                    SysHandlePermissionsAttrs newAttr = new SysHandlePermissionsAttrs();
                    BeanUtils.copyProperties(attr, newAttr, "handlePermission");
                    delAttr.add(attr);
                    attrsClone.add(newAttr);
                }
            }

            shp.setClasses(classesClone);
            shp.setStyles(stylesClone);
            shp.setEvents(eventsClone);
            shp.setAttrs(attrsClone);

            if (redisCanUse) {
                try {
                    //*********Redis 缓存*********
                    RedisClient.del(key);
                    RedisClient.set(key, JSONUtil.toJsonStr(shp));
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            } else {
                //*********本地缓存***********
                // 移除缓存
                removeCacheHandlePermission(shp);
                // 添加缓存
                Element element = new Element(key, shp);
                handlePermissionEhcache.put(element);
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("load handle permissions success(" + (endTime - startTime) + " ms)");
    }

    /**
     * 移除缓存中指定的操作权限
     *
     * @param entity 操作权限对象
     */

    public static void removeCacheHandlePermission(SysHandlePermissions entity) {
        if (RedisClient.isCanUse()) {//Redis 缓存
            String key = getHandlePermissionCacheKey(entity);
            log.info("正在从redis缓存服务器中移除缓存权限：" + key);
            RedisClient.del(key);
        } else {//本地缓存
            String key = getHandlePermissionCacheKey(entity);
            boolean contains = handlePermissionEhcache.getKeys().contains(key);
            if (contains) {
                // 删除已缓存的操作权限
                log.info("正在从本地缓存中移除缓存权限：" + key);
                handlePermissionEhcache.remove(key);
            }
        }
    }

    /**
     * @return 登录用户私有菜单权限分配缓存后缀
     */
    public static String getCacheUserPermissionAllotSuffix() {
        return cacheUserPermissionAllotSuffix;
    }

    /**
     * @return 登录用户拥有的角色所对应的菜单权限后缀
     */
    public static String getCacheRolePermissionAllotSuffix() {
        return cacheRolePermissionAllotSuffix;
    }

    /**
     * 根据操作权限id获取操作对象
     *
     * @param suffixKey 操作权限id
     * @return
     */
    @SuppressWarnings("unchecked")
    public static SysHandlePermissions getCacheHandlePermission(Object loginUserId, String suffixKey) {
        String privatePermissionCachekey = loginUserId + getCacheUserPermissionAllotSuffix();//用户私有的操作权限缓存key
        String rolePermissionCacheKey = loginUserId + getCacheRolePermissionAllotSuffix();//用户所属角色的操作权限缓存key
        if (loginUserId != null && onlineUserPermissionAllotEhcache != null) {
            if (RedisClient.isCanUse()) {//Redis 缓存
                // 从用户私有操作权限中查找
                String privatePermissionCacheJsonStr = RedisClient.get(privatePermissionCachekey);
                if (StringUtils.isNotBlank(privatePermissionCacheJsonStr)) {
                    JSONArray privatePermissionCacheJsonArray = JSONArray.fromObject(privatePermissionCacheJsonStr);
                    for (int i1 = 0, size1 = privatePermissionCacheJsonArray.size(); i1 < size1; i1++) {
                        JSONObject privatePermissionCacheJson = privatePermissionCacheJsonArray.getJSONObject(i1);
                        if (privatePermissionCacheJson != null && privatePermissionCacheJson.containsKey("id")) {
                            String adminUserPermissionAllotId = privatePermissionCacheJson.getString("id");
                            String key = getSysHandlePermissionKey(suffixKey, adminUserPermissionAllotId, null);
                            SysHandlePermissions shp = getSysHandlePermissions(key);
                            if (shp != null) {
                                if (!shp.getIsForbidden()) {
                                    return shp;
                                } else {
                                    break;
                                }
                            }
                        }
                    }
                }
                // 从用户所属角色拥有的操作权限中查找
                String rolePermissionCacheJsonStr = RedisClient.get(rolePermissionCacheKey);
                if (StringUtils.isNotBlank(rolePermissionCacheJsonStr)) {
                    JSONArray privatePermissionCacheJsonArray = JSONArray.fromObject(rolePermissionCacheJsonStr);
                    for (int i1 = 0, size1 = privatePermissionCacheJsonArray.size(); i1 < size1; i1++) {
                        JSONObject rolePermissionCacheJson = privatePermissionCacheJsonArray.getJSONObject(i1);
                        if (rolePermissionCacheJson != null && rolePermissionCacheJson.containsKey("id")) {
                            String rolePermissionAllotId = rolePermissionCacheJson.getString("id");
                            String key = getSysHandlePermissionKey(suffixKey, null, rolePermissionAllotId);
                            SysHandlePermissions shp = getSysHandlePermissions(key);
                            if (shp != null) {
                                if (!shp.getIsForbidden()) {
                                    return shp;
                                } else {
                                    break;
                                }
                            }
                        }
                    }
                }

                //}
            } else {//本地缓存
                // 从用户私有操作权限中查找
                Element element_userPermissionAllot = onlineUserPermissionAllotEhcache.get(privatePermissionCachekey);
                if (element_userPermissionAllot != null) {
                    Object value = element_userPermissionAllot.getObjectValue();
                    if (value instanceof List) {
                        List<SysAdminUserJoinSysMenuPermissions> sajsmpList = (List<SysAdminUserJoinSysMenuPermissions>) value;
                        for (SysAdminUserJoinSysMenuPermissions sajsmp : sajsmpList) {
                            String adminUserPermissionAllotId = sajsmp.getId();
                            SysHandlePermissions shp = getEhCachePermission(suffixKey, adminUserPermissionAllotId, null);
                            if (shp != null) {
                                if (!shp.getIsForbidden()) {
                                    return shp;
                                } else {
                                    handlePermissionEhcache.remove(getHandlePermissionCacheKey(shp));// 如果已被禁用，则从缓存中移除
                                    break;
                                }
                            }
                        }
                    }
                }
                // 从用户所属角色拥有的操作权限中查找
                Element element_rolePermissionAllot = onlineUserPermissionAllotEhcache.get(rolePermissionCacheKey);
                if (element_rolePermissionAllot != null) {
                    Object value = element_rolePermissionAllot.getObjectValue();
                    if (value instanceof List) {
                        List<SysRoleJoinSysMenuPermissions> srjsmpList = (List<SysRoleJoinSysMenuPermissions>) value;
                        for (SysRoleJoinSysMenuPermissions srjsmp : srjsmpList) {
                            String rolePermissionAllotId = srjsmp.getId();
                            SysHandlePermissions shp = getEhCachePermission(suffixKey, null, rolePermissionAllotId);
                            if (shp != null) {
                                if (!shp.getIsForbidden()) {
                                    return shp;
                                } else {
                                    handlePermissionEhcache.remove(getHandlePermissionCacheKey(shp));// 如果已被禁用，则从缓存中移除
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 拼接缓存key
     *
     * @param suffixKey                  操作权限后缀
     * @param adminUserPermissionAllotId 针对单个管理员的权限分配id
     * @param rolePermissionAllotId      针对角色的权限分配id
     * @return
     */
    private static String getSysHandlePermissionKey(String suffixKey, String adminUserPermissionAllotId, String
            rolePermissionAllotId) {
        String handlePermissionIdentifier = StringUtils.substringBeforeLast(suffixKey, separator);
        String code = StringUtils.substringAfterLast(suffixKey, separator);
        SysHandlePermissions tempShp = new SysHandlePermissions();
        tempShp.setAdminUserPermissionAllotId(adminUserPermissionAllotId);
        tempShp.setRolePermissionAllotId(rolePermissionAllotId);
        tempShp.setCode(code);
        tempShp.setHandlePermissionIdentifier(handlePermissionIdentifier);
        return getHandlePermissionCacheKey(tempShp);
    }

    /**
     * 从redis缓存服务器中获取指定key的操作权限
     *
     * @param key 操作权限key
     * @return
     */
    private static SysHandlePermissions getSysHandlePermissions(String key) {
        Map<String, Class> classMap = new HashMap<String, Class>();
        classMap.put("classes", SysHandlePermissionsClasses.class);
        classMap.put("styles", SysHandlePermissionsStyles.class);
        classMap.put("events", SysHandlePermissionsEvents.class);
        classMap.put("attrs", SysHandlePermissionsAttrs.class);
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setRootClass(SysHandlePermissions.class);
        jsonConfig.setClassMap(classMap);
        jsonConfig.setJavaPropertyFilter((Object targetObj, String propertyName, Object value) -> {
            if (propertyName != null && propertyName.equals("createTime") && value != null && !(value instanceof JSONNull)) {
                Date parse = DateUtil.parse(value.toString(), "yyyy-MM-dd HH:mm:ss");
                Timestamp createTime = new Timestamp(parse.getTime());
                if (targetObj instanceof SysHandlePermissionsClasses) {
                    ((SysHandlePermissionsClasses) targetObj).setCreateTime(createTime);
                    return true;
                } else if (targetObj instanceof SysHandlePermissionsStyles) {
                    ((SysHandlePermissionsStyles) targetObj).setCreateTime(createTime);
                    return true;
                } else if (targetObj instanceof SysHandlePermissionsEvents) {
                    ((SysHandlePermissionsEvents) targetObj).setCreateTime(createTime);
                    return true;
                } else if (targetObj instanceof SysHandlePermissionsAttrs) {
                    ((SysHandlePermissionsAttrs) targetObj).setCreateTime(createTime);

                }
                return true;
            }
            return false;
        });
        SysHandlePermissions shp = (SysHandlePermissions) JSONUtil.jsonToBean(RedisClient.get(key), jsonConfig);
        if (shp != null) {
            Boolean isForbidden = shp.getIsForbidden();
            if (isForbidden == null) {
                isForbidden = false;
            }
            if (!isForbidden) {
                return shp;
            } else {
                log.info("由于操作权限" + key + "被禁用，正在从redis缓存移除!");
                RedisClient.del(key);// 如果已被禁用，则从缓存中移除
            }
        }
        return null;
    }

    /**
     * 从本地ehcache权限缓存容器中取出指定key的权限对象
     *
     * @param suffixKey                  权限缓存key后缀，格式：菜单权限Id-具体操作权限编码
     * @param adminUserPermissionAllotId 私有权限分配Id
     * @param rolePermissionAllotId      角色权限分配Id
     * @return
     */
    private static SysHandlePermissions getEhCachePermission(String suffixKey, String
            adminUserPermissionAllotId, String rolePermissionAllotId) {
        String handlePermissionIdentifier = StringUtils.substringBeforeLast(suffixKey, separator);
        String code = StringUtils.substringAfterLast(suffixKey, separator);
        SysHandlePermissions shp = new SysHandlePermissions();
        shp.setAdminUserPermissionAllotId(adminUserPermissionAllotId);
        shp.setRolePermissionAllotId(rolePermissionAllotId);
        shp.setCode(code);
        shp.setHandlePermissionIdentifier(handlePermissionIdentifier);
        String key = getHandlePermissionCacheKey(shp);

        Element element = handlePermissionEhcache.get(key);
        if (element != null) {
            Object shpObj = element.getObjectValue();
            if (shpObj != null) {
                return (SysHandlePermissions) shpObj;
            }
        }
        return null;
    }

    /**
     * 操作权限缓存key
     *
     * @param shp 操作权限对象
     * @return
     */
    public static String getHandlePermissionCacheKey(SysHandlePermissions shp) {
        if (shp == null) {
            return null;
        }
        StringBuffer key = new StringBuffer(HANDLEPERMISSIONCACHEKEYIDENTIFYING);
        String rolePermissionAllotId = shp.getRolePermissionAllotId();
        if (rolePermissionAllotId != null) {
            key.append(rolePermissionAllotId);
            key.append(separator);
        }
        String adminUserPermissionAllotId = shp.getAdminUserPermissionAllotId();
        if (adminUserPermissionAllotId != null) {
            key.append(adminUserPermissionAllotId);
            key.append(separator);
        }
        key.append(shp.getHandlePermissionIdentifier());
        key.append(separator);
        key.append(shp.getCode());
        return key.toString();
    }
}
